package com.cloud.quickcore.shiro;


import com.cloud.quickcommon.exception.BusinessException;
import com.cloud.quickcore.admin.dao.SysUserRepository;
import com.cloud.quickcore.admin.entity.SysPermission;
import com.cloud.quickcore.admin.entity.SysRole;
import com.cloud.quickcore.admin.entity.SysUser;
import com.cloud.quickcore.shiro.jwt.JWTToken;
import com.cloud.quickcore.shiro.jwt.JWTUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Set;
import java.util.stream.Collectors;


@Component
public class MyRealm extends AuthorizingRealm {

    @Autowired
    private SysUserRepository sysUserRepository;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

       // String account = JWTUtil.getUserNo(principalCollection.toString()); 这里因为登陆成功塞入容器是用户名 不需要token得到用户名 如果要得到token解析用户名 在验证成功后new SimpleAuthenticationInfo改
        /**查询用户*/
        SysUser sysUser = sysUserRepository.findSysUserByUsername(principalCollection.toString()).orElseThrow(() -> new BusinessException("用户名不存在!"));
        Set<SysRole> roles = sysUser.getRoles();
        /**获取用户角色*/
        authorizationInfo.addRoles(roles.stream().map(SysRole::getRoleCode).collect(Collectors.toSet()));
        /**获取菜单信息*/
        for(SysRole sysRole:roles){
            authorizationInfo.addStringPermissions(sysRole.getPermissions().stream().filter(permission->StringUtils.isNotEmpty(permission.getCode())).map(SysPermission::getCode).collect(Collectors.toSet()));
        }
        return authorizationInfo;
    }

    /**
     * 用户信息检测
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
        String token = (String) auth.getCredentials();
        // 解密获得username，用于和数据库进行对比
        String username = JWTUtil.getUserNo(token);
        if (username == null) {
            throw new AuthenticationException("token无效");
        }

        SysUser sysUser = sysUserRepository.findSysUserByUsername(username).orElseThrow(() -> new BusinessException("用户名不存在!"));

        if (!JWTUtil.verify(token, username, sysUser.getPassword())) {
            throw new AuthenticationException("token已过期!");
        }
        return new SimpleAuthenticationInfo(sysUser.getUsername(), token, getName());
    }
}
